import axios from 'axios'
import CryptoJS from 'crypto-js'
import { includes } from 'lodash-es'
import { notification } from 'ant-design-vue'
import router from '@/router'
import { t } from '@/libs/utils/i18n'

const Api = {
	generateFormParams: (params: any = {}) => {
		const jwtToken = useTokenStore(Pinia)
		const languageStore = useLanguageStore(Pinia)
		const currencyStore = useCurrencyStore(Pinia)
		const _timestamp = Tool.getTimestamp()
		let _nonce = `${_timestamp}_nonce_`
		_nonce += Math.random() + Math.random() + Math.random() + Math.random()
		params.token = jwtToken.getPayload.token
		params.key = jwtToken.key
		params.nonce = _nonce
		params.timestamp = _timestamp
		params.language = languageStore.currentLanguage
		params.currency = currencyStore.currentCurrency
		delete params['sign']
		delete params['ufile']
		delete params['ufile[]']
		// console.log('params', params)
		const keys = Object.keys(params)
		keys.sort()
		const arr = []
		for (const index in keys) {
			arr[index] = `${keys[index]}=${params[keys[index]]}`
		}
		let _sign = arr.join('&')
		_sign = CryptoJS.MD5(_sign).toString()
		params.sign = _sign
		delete params.token
		delete params.key
		return params
	},
	guestPost: function (uri: string, formParams: any = {}, isLoading: boolean = false) {
		return this.post(uri, formParams, isLoading, false)
	},
	post(uri: string, formParams: any = {}, isLoading: boolean = false, isAuth: boolean = true) {
		const Loading = useLoadingStore(Pinia)
		if (isLoading) Loading.open()
		formParams = Tool.removeEmptyObjValues(formParams)
		let canPost = true
		const url = import.meta.env.VITE_API_DOMAIN + import.meta.env.VITE_API_URI + uri
		const headers = {
			'content-type': 'application/x-www-form-urlencoded;charset=UTF-8',
			Authorization: undefined
		}
		if (isAuth) {
			const jwtToken = useTokenStore(Pinia)
			const token = jwtToken.getToken
			if (token) {
				const jwtToken = useTokenStore(Pinia)
				const _timestamp = Tool.getTimestamp()
				if (jwtToken.getPayload.end_at < _timestamp) {
					canPost = false
				} else {
					headers.Authorization = `Bearer ${token}`
					formParams = Api.generateFormParams(formParams)
				}
			} else {
				canPost = false
			}
			if (!canPost) {
				jwtToken.updateToken()
				if (isLoading) Loading.close()
				this.notify(t('通知.登录令牌已过期'))
				return router.push({ path: '/login' })
				// return new Promise((resolve, reject) => {})
			}
		}
		return new Promise((resolve, reject) => {
			axios
				.create({
					baseURL: url,
					headers: headers
				})
				.post('', formParams)
				.then(res => {
					// console.log('then')
					const resData = this.handleResData(res)
					if (resData) {
						resolve(resData)
					} else {
						if (isLoading) Loading.close()
						return new Promise((resolve1, reject1) => {})
					}
				})
				.catch(res => {
					// console.log('catch')
					if (isLoading) Loading.close()
					this.handleResData(res)
					return new Promise((resolve1, reject1) => {})
				})
				.finally(() => {
					// console.log('finally')
					if (isLoading) Loading.close()
					return new Promise((resolve1, reject1) => {})
				})
		}).catch(() => {
			if (isLoading) Loading.close()
			return new Promise((resolve1, reject1) => {})
		})
	},
	handleResData(res: any) {
		if (res.status === 200) {
			const data1 = res.data
			if (data1.code !== 200) {
				this.notify(data1.message || t('通知.接口异常'))
				return false
			} else {
				return data1.data
			}
		} else {
			if (!res.response) {
				this.notify(res.message || JSON.stringify(res))
				return false
			}
			const status1 = res.response.status
			const data1 = res.response.data
			const _status1 = parseFloat(import.meta.env.VITE_RE_LOGIN_STATUS_CODE)
			if (status1 === _status1) {
				const jwtToken = useTokenStore(Pinia)
				jwtToken.updateToken()
				this.notify(t('通知.登录认证异常'))
				return router.push({ path: '/login' })
			} else {
				this.notify(data1.message || t('通知.请求异常'))
				return false
			}
		}
	},
	notify(msg: string = ''): void {
		notification.open({
			message: msg,
			placement: 'topRight'
		})
	},
	hasPermission(permission = ''): boolean {
		const adminer = useAdminerStore()
		if (adminer.getAdminer.is_super === Enums.common.isDatas.Y[0]) {
			return true
		}
		let can = Enums.common.isDatas.N[0]
		if (permission === '') {
			can = Enums.common.isDatas.Y[0]
		} else {
			if (includes(adminer.getPermissions, permission)) {
				can = Enums.common.isDatas.Y[0]
			}
		}
		return can === Enums.common.isDatas.Y[0]
	},
	authThen(permission = '', callback: () => void) {
		if (permission === '') {
			callback()
		} else {
			const formParams = {
				permission
			}
			this.post('/rbac/adminer/is-auth-permission', formParams, true).then((res: any) => {
				if (res.can === Enums.common.isDatas.Y[0]) {
					const adminer = useAdminerStore()
					adminer.updateAdminer(res.authInfo.adminerInfo)
					adminer.updatePermissions(res.authInfo.permissionPaths)
					callback()
				} else {
					const jwtToken = useTokenStore(Pinia)
					jwtToken.updateToken()
					this.notify(t('通知.授权失败请重新登录'))
					return router.push({ path: '/login' })
				}
			})
		}
	},
	authTo(permission = '', path: string): void {
		this.authThen(permission, () => {
			router.push({ path }).then()
		})
	}
}

export default Api
